package com.web.controoller;

import com.web.constant.DataPackageConstants;
import com.web.pojo.domain.Device;
import com.web.pojo.domain.DeviceGroup;
import com.web.pojo.dto.*;
import com.web.pojo.vo.CommonResult;
import com.web.service.DeviceGroupServer;
import com.web.service.DeviceServer;
import com.web.service.NetworkServer;
import com.web.utils.DownLinkDataUtil;
import com.web.utils.RedisUtil;
import com.web.utils.SecurityUtils;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: wws
 * describe:
 */
@CrossOrigin
@RestController
@RequestMapping("/deviceOperation")
public class DeviceOperation {

    @Autowired
    DeviceServer deviceServer;

    @Autowired
    NetworkServer networkServer;

    @Autowired
    DeviceGroupServer deviceGroupServer;

    @Autowired
    RedisUtil redisUtil;

    @PostMapping("/setSwitchState")
    @ApiOperation("设置开关状态")
    public CommonResult setSwitchState(@RequestBody SetSwitchStateDTO dto) {
        System.out.println(dto);
        Device device = deviceServer.selectDeviceDetails(dto.getId());
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
//          byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        System.out.println(device.getDeviceAddr());
        System.out.println("FCNT");
        show(fCnt);
        byte[] FRMPayload = DownLinkDataUtil.switchStatePayLoad(fCnt, dto.getDeviceChannelParameter1(), dto.getDeviceChannelParameter2());

        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            deviceServer.updateDeviceSwitchState(dto);
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");
        }
    }

    @PostMapping("/getSwitchState")
    @ApiOperation("获取开关状态")
    public CommonResult getSwitchState(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.switchStatePayLoad(fCnt);
//        return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_LIGHT_STATUS);

        SetSwitchStateDTO setSwitchStateDTO = new SetSwitchStateDTO(1, (byte) 0, (byte) 1);
        return CommonResult.select(setSwitchStateDTO);

    }

    @PostMapping("/setSwitchControl")
    @ApiOperation("设置开关控制")
    public CommonResult setSwitchControl(@RequestBody SetSwitchControlStateDTO dto) {
        Device device = deviceServer.selectDeviceDetails(dto.getId());
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.switchControlPayLoad(fCnt, dto);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            deviceServer.updateDeviceSwitchControlState(dto);
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");

        }
    }

    @PostMapping("/getSwitchControl")
    @ApiOperation("获取开关控制")
    public CommonResult getSwitchControl(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.switchControlPayLoad(fCnt);
        return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_CONTROL_STATUS);

    }

    @PostMapping("/setSwitchSchedule")
    @ApiOperation("设置开关时间表")
    public CommonResult setSwitchSchedule(@RequestBody SetSwitchScheduleDTO dto) {
        Device device = deviceServer.selectDeviceDetails(dto.getId());
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.switchSchedulePayLoad(fCnt, dto);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            deviceServer.replaceDeviceSwitchSchedule(dto);
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");
        }
    }

    @PostMapping("/getSwitchSchedule")
    @ApiOperation("获取开关时间表")
    public CommonResult getSwitchSchedule(@RequestBody SetSwitchScheduleDTO dto) {
        Device device = deviceServer.selectDeviceDetails(dto.getId());
        // if (device == null) {
        //     return CommonResult.error("设备不存在");
        // }
        // byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        // byte[] FRMPayload = DownLinkDataUtil.switchSchedulePayLoad(fCnt, dto.getChannel());
        // return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_SCHEDULE);
        List<ScheduleDTO> schedule = new ArrayList<>();
        schedule.add(new ScheduleDTO((byte) 1,(byte) 2,(byte) 3,(byte) 4));
        schedule.add(new ScheduleDTO((byte) 1,(byte) 2,(byte) 3,(byte) 4));

        schedule.add(new ScheduleDTO((byte) 1,(byte) 2,(byte) 3,(byte) 4));

        SetSwitchScheduleDTO setSwitchScheduleDTO = new SetSwitchScheduleDTO(dto.getId(),(byte) 2,schedule);
        return CommonResult.select(setSwitchScheduleDTO);
    }

    @PostMapping("/setSwitchDimmingLevel")
    @ApiOperation("设置开关调光等级")
    public CommonResult switchSchedule(@RequestBody SetSwitchDimmingLevelDTO dto) {
        Device device = deviceServer.selectDeviceDetails(dto.getId());
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.switchDimmingLevel(fCnt, dto);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            deviceServer.updateDeviceSwitchDimmingLevel(dto);
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");
        }
    }

    @PostMapping("/getSwitchDimmingLevel")
    @ApiOperation("获取开关调光等级")
    public CommonResult getSwitchDimmingLevel(@RequestBody Integer id) {
        Device device = deviceServer.selectDeviceDetails(id);
        // if (device == null) {
        //     return CommonResult.error("设备不存在");
        // }
        // byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        // byte[] FRMPayload = DownLinkDataUtil.switchDimmingLevel(fCnt);
        // return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_DIMMING_LEVEL);
        //
        SetSwitchDimmingLevelDTO setSwitchDimmingLevelDTO = new SetSwitchDimmingLevelDTO(device.getDeviceId(), (byte) 1,(byte) 1);

        return CommonResult.select(setSwitchDimmingLevelDTO);
    }

    @PostMapping("/getSwitchDeviceStatus")
    @ApiOperation("获取开关的温度、湿度、露点、电源/电量、设备状态")
    public CommonResult getSwitchDeviceStatus(@RequestBody Integer id) {
        Device device = deviceServer.selectDeviceDetails(id);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.getSwitchDeviceStatus(fCnt);
        return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_DEVICE_ATTRIBUTES);
    }

    @PostMapping("/setSwitchReportingPeriod")
    @ApiOperation("设置上报周期")
    public CommonResult setSwitchReportingPeriod(@RequestBody SetSwitchReportingPeriodDTO dto) {
        System.out.println(dto);
        Device device = deviceServer.selectDeviceDetails(dto.getId());
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.switchReportingPeriod(fCnt, dto);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            deviceServer.updateDeviceSwitchReportingPeriod(dto);
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");

        }
    }

    @PostMapping("/getSwitchReportingPeriod")
    @ApiOperation("获取上报周期")
    public CommonResult getSwitchReportingPeriod(@RequestBody Integer id) {
        Device device = deviceServer.selectDeviceDetails(id);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.switchReportingPeriod(fCnt);
        return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_REPORTING_PERIOD);
    }

    @PostMapping("/getSwitchOperatingHours")
    @ApiOperation("获取开关工作时间")
    public CommonResult getSwitchOperatingHours(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.getOperatingHours(fCnt);
        return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_OPERATING_HOURS);
    }

    @PostMapping("/setAppKey")
    @ApiOperation("设置开关的APPKEY")
    public CommonResult setAppKey(@RequestBody SetSwitchAppKeyDTO dto) {
        Device device = deviceServer.selectDeviceDetails(dto.getId());
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.setAppKey(fCnt, dto);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");

        }
    }

    @PostMapping("/getAppKey")
    @ApiOperation("获取开关的APPKEY")
    public CommonResult getAppKey(@RequestBody Integer id) {
        Device device = deviceServer.selectDeviceDetails(id);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.setAppKey(fCnt);
        return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_APPKEY);
    }

    @PostMapping("/getDeviceType")
    @ApiOperation("获取设备类型、初始化上行通道、版本号")
    public CommonResult getDeviceType(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.getDeviceType(fCnt);
        return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_GET_INFO);
    }

    @PostMapping("/deleteDeviceGroup")
    @ApiOperation("删除一个终端所有分组")
    public CommonResult deleteGroup(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.deleteDeviceGroup(fCnt);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");
        }
    }

    @PostMapping("/selectDeviceGroup")
    @ApiOperation("删除一个终端所有分组")
    public CommonResult selectDeviceGroup(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.selectDeviceGroup(fCnt);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");
        }
    }


    @PostMapping("/deviceReboot")
    @ApiOperation("终端重启")
    public CommonResult deviceReboot(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.deviceReboot(fCnt);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");
        }
    }


    @PostMapping("/deviceReset")
    @ApiOperation("恢复终端默认设置")
    public CommonResult deviceReset(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.deviceReset(fCnt);
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");
        }
    }

    @PostMapping("/setDeviceTime")
    @ApiOperation("设置设备时间")
    public CommonResult setDeviceTime(@RequestBody SetDeviceTimeDTO dto) {
        Device device = deviceServer.selectDeviceDetails(dto.getId());
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.setDeviceTime(fCnt, dto.getDay(), dto.getMonth(), dto.getYear(), dto.getSecond(), dto.getMinute(), dto.getHour());
        if (networkServer.setSwitch(device, fCnt, FRMPayload)) {
            return CommonResult.success("操作成功");
        } else {
            return CommonResult.fail("操作失败");
        }
    }

    @PostMapping("/getDeviceTime")
    @ApiOperation("获得设备时间")
    public CommonResult getDeviceTime(@RequestBody Integer deviceId) {
        Device device = deviceServer.selectDeviceDetails(deviceId);
        // if (device == null) {
        //     return CommonResult.error("设备不存在");
        // }
        // byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        // byte[] FRMPayload = DownLinkDataUtil.getDeviceTime(fCnt);
        // return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_DELETE_TIME);
        SetDeviceTimeDTO setDeviceTimeDTO = new SetDeviceTimeDTO(device.getDeviceId(),(byte)1,(byte)1,(byte)1,(byte)1,(byte)1,(byte)1);
        return CommonResult.select(setDeviceTimeDTO);
    }


    @PostMapping("/setDeviceGroupByDevice")
    @ApiOperation("给设备分配设备组")
    public CommonResult setDeviceGroupByDevice(@RequestBody SetDeviceGroupByDeviceDTO dto) {
        Device device = deviceServer.selectDeviceDetails(dto.getDeviceId());
        if (device == null) {
            return CommonResult.error("设备不存在");
        }
        List<DeviceGroup> groupAddrList = deviceGroupServer.selectDeviceGroupAddrById(dto.getDeviceGroupIds());
        if (groupAddrList.size() == 0) {
            return CommonResult.error("设备组不存在");
        }
        byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
        byte[] FRMPayload = DownLinkDataUtil.setDeviceGroupByDevice(fCnt, groupAddrList.get(0).getDeviceGroupAppkey(), groupAddrList.get(0).getDeviceGroupAddr());
        System.out.println("FRMPayload");
        show(FRMPayload);
        if (networkServer.deviceGrouping(device, fCnt, FRMPayload)) {
            return CommonResult.insert(deviceGroupServer.addDeviceToDeviceGroup(dto.getDeviceId(), dto.getDeviceGroupIds()));
        } else {
            return CommonResult.fail("操作失败");
        }
    }

//    @PostMapping("/getDeviceGroup")
//    @ApiOperation("查看设备的设备组")
//    public CommonResult getDeviceGroup(@RequestBody  Integer deviceId) {
//        Device device = deviceServer.selectDeviceDetails(deviceId);
//        if (device == null) {
//            return CommonResult.error("设备不存在");
//        }
//          byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
//
//    }

    @PostMapping("/selectAssignableDeviceGroup")
    @ApiOperation("查询可以分配的用户组")
    public CommonResult selectAssignableDeviceGroup(@RequestBody Integer deviceId) {
        Integer userId = SecurityUtils.getUserId();
        List<DeviceGroup> list = deviceGroupServer.selectAssignableDeviceGroup(deviceId, userId);

        return CommonResult.select(list);
    }


    @PostMapping("/selectRegisteredDeviceList")
    @ApiOperation("查询已经入网的设备 ")
    public CommonResult selectRegisteredDeviceByAddressId(@RequestBody SelectRegisteredDeviceDTO dto) {
        dto.setUserId(SecurityUtils.getUserId());
        List<Device> list = deviceServer.selectRegisteredDeviceByAddressId(dto);
        return CommonResult.select(list);
    }
    @PostMapping("/selectRegisteredBulbList")
    @ApiOperation("查询已经入网的设备 ")
    public CommonResult selectRegisteredBulbList(@RequestBody SelectRegisteredDeviceDTO dto) {
        dto.setUserId(SecurityUtils.getUserId());
        List<Device> list = deviceServer.selectRegisteredDeviceByAddressId(dto);
        return CommonResult.select(list);
    }

//    @PostMapping("/setDeviceGroupByDevice")
//    @ApiOperation("给设备分配设备组")
//    public CommonResult setDeviceGroupByDevice(@RequestBody SetDeviceGroupByDeviceDTO dto) {
//        Device device = deviceServer.selectDeviceDetails(dto.getDeviceId());
//        if (device == null) {
//            return CommonResult.error("设备不存在");
//        }
//        List<DeviceGroup> groupAddrList = deviceGroupServer.selectDeviceGroupAddrById(dto.getDeviceGroupIds());
//        Map<String, List<String>> appKeyMap = testGroup(groupAddrList);
//        for (String key:appKeyMap.keySet()){
//            List<String> a =appKeyMap.get(key);
//            if (a.size()<=4){
//                  byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
//                byte[] FRMPayload = DownLinkDataUtil.setDeviceGroupByDevice(fCnt, a);
//            }
//
//        }
//
//          byte[] fCnt = redisUtil.getFRMPayloadFCnt(device.getDeviceAddr());
//        byte[] FRMPayload = DownLinkDataUtil.setDeviceGroupByDevice(fCnt, groupAddrList);
//
//        return networkServer.getSwitch(device, fCnt, FRMPayload, DataPackageConstants.SWITCH_APPKEY);
//    }
//
//    Map<String, List<String>> testGroup(List<DeviceGroup> groupAddrList) {
//        Map<String, List<String>> resultMap = new HashMap<>();
//        for (DeviceGroup deviceGroup : groupAddrList) {
//            String key = deviceGroup.getDeviceGroupAppkey();
//            if (resultMap.containsKey(key)) {//map中已存在，将该数据存放到同一个key的map中
//                resultMap.get(key).add(deviceGroup.getDeviceGroupAddr());
//            } else {//map中不存在，新建key，用来存放数据
//                List<String> tmpList = new ArrayList<>();
//                tmpList.add(deviceGroup.getDeviceGroupAddr());
//                resultMap.put(key, tmpList);
//            }
//
//
//        }
//        return resultMap;
//    }

    public static void show(byte[] b) {
        for (int i = 0; i < b.length; i++) {
            System.out.printf("%02x ", b[i]);
        }
        System.out.println();
    }
}
